package com.zwzc;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.zwzc.module.sys.entity.SysMenu;
import com.zwzc.module.sys.entity.SysUser;
import com.zwzc.sys.SysRoleAuthFeign;
import com.zwzc.sys.SysUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ProjectName: zwzc
 * @ClassName: MyUserDetailsService
 * @Author: hejialun
 * @Description: secuity获取用户接口
 * @Date: 2021/6/22 13:08
 */
@Service
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    private SysUserFeign sysUserFeign;

    @Resource
    private SysRoleAuthFeign sysRoleAuthFeign;

    @Resource
    private RedisUtil redisUtil;
    //过期时间
    @Value("${jwt.expireTime:3600}")
    public long EXPIRE_TIME;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser sysUser = sysUserFeign.getUserInfoByUsernameAll(username).getData();
        if (sysUser == null) {      //用户不存在，认证失败
            throw new UsernameNotFoundException("用户名不存在");
        }
        ////用户已被禁用，认证失败
        if (!StrUtil.equals(sysUser.getState(), DicConstants.State.ENABLE)) {
            throw new HtException("用户已被禁用！请联系管理员");
        }
        //定义权限集合对象
        List<GrantedAuthority> auths = new ArrayList<>();
        //定义权限数组
        List<String> roleCodes = new ArrayList<>();
        //定义菜单权限数组
        List<String> menuCodes = new ArrayList<>();
        //获取缓存中的数据
        Map<String, String> roleMap = (Map<String, String>) redisUtil.get(RedisConstants.USER_ROLE + username);
        if (ObjectUtil.isEmpty(roleMap)) {
            //查询出
            //获取用户按钮权限和菜单权限
            List<SysMenu> sysMenuList = sysUser.getSysMenusNoTree();
            //设置角色权限集合
            roleCodes = sysUser.getRoleObjs().stream().map(x -> x.getCode()).collect(Collectors.toList());
            //设置菜单权限集合
            menuCodes = sysMenuList.stream().map(SysMenu::getCode).collect(Collectors.toList());
            //缓存到redis里面
            roleMap = new HashMap<>();
            //设置角色权限
            roleMap.put(RedisConstants.SYS_ROLE_CODES, String.join(",", roleCodes));
            //设置菜单
            roleMap.put(RedisConstants.SYS_MENU_CODES, String.join(",", menuCodes));
            //将用户权限信息存到redis
            redisUtil.set(RedisConstants.USER_ROLE + sysUser.getUsername(), roleMap, EXPIRE_TIME);
        } else {
            //从缓存中获取权限
            roleCodes = Arrays.asList(roleMap.get(RedisConstants.SYS_ROLE_CODES).split(","));
            menuCodes = Arrays.asList(roleMap.get(RedisConstants.SYS_MENU_CODES).split(","));
        }
        //设置角色权限
        auths.addAll(roleCodes.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
        //设置功能权限
        auths.addAll(menuCodes.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));
        return new User(sysUser.getUsername(), sysUser.getPassword(), auths);
    }
}